package com.taobao.home.service.impl;


import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.taobao.base.model.PageParams;
import com.taobao.base.model.PageResult;
import com.taobao.base.model.RestResponse;
import com.taobao.home.feignclient.SearchServiceClient;
import com.taobao.home.mapper.GoodsMapper;
import com.taobao.home.mapper.GoodsSubcategoryMapper;
import com.taobao.home.mapper.ProcessMapper;
import com.taobao.home.model.dto.*;
import com.taobao.home.model.po.Goods;
import com.taobao.home.model.po.GoodsDetails;
import com.taobao.home.model.po.GoodsSubcategory;
import com.taobao.home.model.po.Process;
import com.taobao.home.service.GoodsService;
import com.taobao.home.service.StoreService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.beans.Transient;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@Service
public class GoodsServiceImpl implements GoodsService {

    @Autowired
    private GoodsMapper goodsMapper;
    @Autowired
    private StoreService storeService;
    @Autowired
    private SearchServiceClient searchServiceClient;
    @Autowired
    private ProcessMapper processMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private GoodsSubcategoryMapper goodsSubcategoryMapper;

    private static String ListToString(List<String> list) {
        if (list == null || list.isEmpty()) {
            return null;
        }
        return String.join(", ", list);
    }

    private static List<String> StringToList(String str) {
        if (str == null || str.trim().isEmpty()) {
            return null;
        }

        try {
            ObjectMapper objectMapper = new ObjectMapper();
            List<String> list = objectMapper.readValue(str, List.class);
            return list;

        } catch (Exception e) {
            e.printStackTrace();
        } // 使用逗号作为分隔符分割字符串
        return null;
    }

    @DS("slave") // 走从库
    @Override
    public RestResponse<List<GoodsDto>> getAllGoods() {

        // 拼装查询条件
        LambdaQueryWrapper<Goods> queryWrapper = new LambdaQueryWrapper<>();
        // 查询所有
        List<Goods> goodsList = goodsMapper.selectList(queryWrapper);

        if (goodsList == null) {
            return RestResponse.validfail("查询失败");
        }
        ArrayList<GoodsDto> goodsDtoslist = new ArrayList<>();

        // 转换
        for (Goods goods : goodsList) {
            GoodsDto goodsDto = new GoodsDto();
            List<String> foodList = StringToList(goods.getFoodTag());
            BeanUtils.copyProperties(goods, goodsDto, "foodTag");
            goodsDto.setFoodTag(foodList);
            goodsDtoslist.add(goodsDto);
        }

        return RestResponse.success(goodsDtoslist);
    }

    @DS("slave") // 走从库
    @Override
    public PageResult<Goods> getGoodsByPage(PageParams pageParams, QueryGoodsParamsDto goodsParamsDto) {

        //拼装查询条件
        LambdaQueryWrapper<Goods> queryWrapper = new LambdaQueryWrapper<>();
        //根据名称模糊查询,在sql中拼接 goods.name like '%值%'
        queryWrapper.like(StringUtils.isNotEmpty(goodsParamsDto.getTitle()), Goods::getTitle, goodsParamsDto.getTitle());
        //根据课程审核状态查询 goods.store.id = ?
        if (goodsParamsDto.getStoresId() != null) {
            queryWrapper.eq(Goods::getStoreId, goodsParamsDto.getStoresId());
        }
        //商品类型态查询 goods._type = ?
        queryWrapper.eq(StringUtils.isNotEmpty(goodsParamsDto.get_types()), Goods::getTypes, goodsParamsDto.get_types());

        //创建page分页参数对象，参数：当前页码，每页记录数
        Page<Goods> page = new Page<>(pageParams.getPageNo(), pageParams.getPageSize());
        //开始进行分页查询
        Page<Goods> pageResult = goodsMapper.selectPage(page, queryWrapper);
        //数据列表
        List<Goods> items = pageResult.getRecords();
        //总记录数
        int total = (int) pageResult.getTotal();

        //List<T> items, int counts, int page, int pageSize
        PageResult<Goods> courseBasePageResult = new PageResult<>(items, total, pageParams.getPageNo(), pageParams.getPageSize());

        return courseBasePageResult;
    }

    @DS("slave") // 走从库
    @Override
    public RestResponse<Goods> getGoodsById(int goodsId) {

        Goods goodsById = goodsMapper.getGoodsById(goodsId);
        if (goodsById == null) {
            return RestResponse.validfail("商品不存在");
        }
        return RestResponse.success(goodsById);
    }

    @DS("slave") // 走从库
    @Override
    public RestResponse<List<GoodsPreviewDto1>> getGoodsByStoreId(int storeId) {
        List<Goods> goodsList = goodsMapper.getGoodsByStoreId(storeId);
        List<GoodsPreviewDto1> goodsPreviewDto1s = new ArrayList<>();
        for (Goods goods : goodsList) {
            GoodsPreviewDto1 goodsPreviewDto1 = new GoodsPreviewDto1();
            RestResponse<StoreDto> storeById = storeService.getStoreById(goods.getStoreId());
            goodsPreviewDto1.setStoreName(storeById.getResult().getStoreName());
            goodsPreviewDto1.setStoreId(goods.getStoreId());
            goodsPreviewDto1.setGoodsId(goods.getGoodsId());
            goodsPreviewDto1.setImgUrl(goods.getImgUrl());
            goodsPreviewDto1.setPrice(goods.getPrice());
            goodsPreviewDto1.setTitle(goods.getTitle());
            goodsPreviewDto1.setLogistics(goods.getLogistics());
            goodsPreviewDto1.setFoodTag(goods.getFoodTag());
            goodsPreviewDto1s.add(goodsPreviewDto1);
        }

        return RestResponse.success(goodsPreviewDto1s);
    }

    @DS("slave") // 走从库
    @Override
    public RestResponse<List<GoodsPreviewDto1>> getStoreIdAndTitle(StoreIdTitle storeIdTitle) {

        List<Goods> goodsList = goodsMapper.queryStoreIdAndTitle(storeIdTitle.getStoreId(), storeIdTitle.getTitle());
        List<GoodsPreviewDto1> goodsPreviewDto1s = new ArrayList<>();
        for (Goods goods : goodsList) {
            GoodsPreviewDto1 goodsPreviewDto1 = new GoodsPreviewDto1();
            RestResponse<StoreDto> storeById = storeService.getStoreById(goods.getStoreId());
            goodsPreviewDto1.setStoreName(storeById.getResult().getStoreName());
            goodsPreviewDto1.setStoreId(goods.getStoreId());
            goodsPreviewDto1.setGoodsId(goods.getGoodsId());
            goodsPreviewDto1.setImgUrl(goods.getImgUrl());
            goodsPreviewDto1.setPrice(goods.getPrice());
            goodsPreviewDto1.setTitle(goods.getTitle());
            goodsPreviewDto1.setLogistics(goods.getLogistics());
            goodsPreviewDto1.setFoodTag(goods.getFoodTag());
            goodsPreviewDto1s.add(goodsPreviewDto1);
        }

        return RestResponse.success(goodsPreviewDto1s);
    }

    @DS("slave") // 走从库
    @Override
    public PageResult<GoodsPreviewDto> getGoodsPreview(PageParams pageParams) {

        List<GoodsPreviewDto> goodsPreviewDtos = goodsMapper.queryPreview((long) pageParams.getPageNo(), (long) pageParams.getPageSize());

        if (goodsPreviewDtos == null) {
            return null;
        }


        return new PageResult<>(goodsPreviewDtos, goodsPreviewDtos.size(), pageParams.getPageNo(), pageParams.getPageSize());
    }

    @DS("slave") // 走从库
    @Override
    public RestResponse<GoodsDetailsDto> getGoodsDetail(int goodsId) {
        GoodsDetails goodsDetail = goodsMapper.getGoodsDetail(goodsId);
        if (goodsDetail == null) {
            return RestResponse.validfail("商品不存在");
        }
        System.err.println(goodsDetail.getImgList());

        GoodsDetailsDto goodsDetailsDto = new GoodsDetailsDto();
        BeanUtils.copyProperties(goodsDetail, goodsDetailsDto, "imgList");
        List<String> imgList = StringToList(goodsDetail.getImgList());
        goodsDetailsDto.setImgList(imgList);

        return RestResponse.success(goodsDetailsDto);
    }

    @DS("master") // 走主库
    @Override
    public RestResponse<String> addGoodsSubCategory(GoodsSubcategoryDto goodsSubcategoryDto) {

        GoodsSubcategory goodsSubcategory = new GoodsSubcategory();

        BeanUtils.copyProperties(goodsSubcategoryDto, goodsSubcategory);

        int insert = goodsSubcategoryMapper.insert(goodsSubcategory);

        if (insert == 0) {
            return RestResponse.validfail("添加失败");
        }

        return RestResponse.success("添加成功");
    }

    @Override
    public RestResponse<List<GoodsSubcategoryDto>> getGoodsSubCategoryByGoodsId(int goodsId) {

        // 构建查询条件
        QueryWrapper<GoodsSubcategory> queryWrapper = new QueryWrapper<>();
        // 根据goodsId查询
        queryWrapper.eq("goods_id", goodsId);
        // 查询所有
        List<GoodsSubcategory> goodsSubcategories = goodsSubcategoryMapper.selectList(queryWrapper);
        // 转成Dto
        List<GoodsSubcategoryDto> goodsSubcategoryDtos = new ArrayList<>();
        for (GoodsSubcategory goodsSubcategory : goodsSubcategories) {
            GoodsSubcategoryDto goodsSubcategoryDto = new GoodsSubcategoryDto();
            BeanUtils.copyProperties(goodsSubcategory, goodsSubcategoryDto);
            goodsSubcategoryDtos.add(goodsSubcategoryDto);
        }
        // 返回
        return RestResponse.success(goodsSubcategoryDtos);

    }

    // 减库存
    @DS("master") // 走主库
    @Override
    public RestResponse<String> getGoodsCount(int goodsId, int num) {

        Goods goods = goodsMapper.getGoodsCountById(goodsId);
        if (goods == null) {
            return RestResponse.validfail("商品不存在");
        }
        if (goods.get_count() < num) {
            return RestResponse.validfail("商品数量不足");
        }
        int i = goodsMapper.updateGoodsCount(goodsId, num);
        System.err.println("9999999999999999999999999999999999999999999");
        // 改库存
        synchronized (this) {
//            int i = goodsMapper.updateGoodsCount(goodsId, num);
            if (i < 1) {
                return RestResponse.validfail("购买失败");
            }
        }
        return RestResponse.success("购买成功");
    }

    @Override
    public RestResponse<String> addGoodsDoc(int goodsId) {
        String msg = "";

        Goods goods = goodsMapper.getGoodsById(goodsId);
        try {
            msg = searchServiceClient.addDoc(goods).getResult();
        } catch (IOException e) {
            return RestResponse.validfail(e.getLocalizedMessage());
        }

        return RestResponse.success(msg);
    }

    @DS("master") // 走主库
    @Override
    @Transient
    public RestResponse<String> addGoods(GoodsDto goodsDto) {

        System.out.println(goodsDto);
        // goodsDto 转换为 goods
        Goods goods = new Goods();
        BeanUtils.copyProperties(goodsDto, goods, "foodTag", "imgList");
        String foodTag = ListToString(goodsDto.getFoodTag());
        String imgList = ListToString(goodsDto.getImgList());
        goods.setFoodTag(foodTag);
        goods.setImgList(imgList);
        // 随机生成id
        goods.setGoodsId(new Random().nextInt(1000000));
        // 调用mapper添加
        int i = goodsMapper.insert(goods);
        if (i == 0) {
            return RestResponse.validfail("添加失败");
        }

        // 添加到es中
        Process process = new Process();
        process.setFileId(goods.getGoodsId());
        process.setTypes(1);
        process.setStatus("1");
        process.setFailCount(0);
        process.setUpdateTime(LocalDateTime.now());
        int i1 = processMapper.insert(process);
        if (i1 == 0) {
            return RestResponse.validfail("添加任务记录失败");
        }


        return RestResponse.success("添加成功");
    }

    @Override
    public RestResponse<List<GoodsPreviewDto1>> getGoodsPreviewByTitle(String title) {
        List<GoodsPreviewDto1> goodsByTitle = new ArrayList<>();

        // 1.先从Rides中获取数据
        ListOperations<String, GoodsPreviewDto1> listOps = redisTemplate.opsForList();
        // 获取列表中的所有元素
        goodsByTitle = listOps.range(title, 0, -1);
        if (goodsByTitle != null && goodsByTitle.size() > 0) {
            return RestResponse.success(goodsByTitle);
        }


        // 2.如果redis中没有数据，则从es中获取数据
        RestResponse<List<GoodsPreviewDto1>> restResponse = searchServiceClient.getGoodsPreviewByTitle(title);
        List<GoodsPreviewDto1> goodsPreviewDto1List = restResponse.getResult();
//        List<GoodsPreviewDto1> goodsPreviewDto1List = searchServiceClient.getGoodsPreviewByTitle(title).getResult();
        System.out.println(goodsPreviewDto1List);
        if (goodsPreviewDto1List.size() != 0 && goodsPreviewDto1List != null) {
            return RestResponse.success(goodsPreviewDto1List);
        }

        // 3.如果es中也没有数据，则从数据库中获取数据，并添加到redis、es中
        List<Goods> goodsList = goodsMapper.getGoodsPreviewByTitle(title);
        for (Goods goods : goodsList) {
            GoodsPreviewDto1 goodsPreviewDto1 = new GoodsPreviewDto1();
            // todo: 改用子线程
            RestResponse<StoreDto> storeById = storeService.getStoreById(goods.getStoreId());
            goodsPreviewDto1.setStoreName(storeById.getResult().getStoreName());
            goodsPreviewDto1.setStoreId(goods.getStoreId());
            goodsPreviewDto1.setGoodsId(goods.getGoodsId());
            goodsPreviewDto1.setImgUrl(goods.getImgUrl());
            goodsPreviewDto1.setPrice(goods.getPrice());
            goodsPreviewDto1.setTitle(goods.getTitle());
            goodsPreviewDto1.setLogistics(goods.getLogistics());
            goodsPreviewDto1.setFoodTag(goods.getFoodTag());
            goodsByTitle.add(goodsPreviewDto1);
        }


        // 将数据添加到redis中
        listOps.rightPushAll(title, goodsByTitle);
        // 设置过期时间为5分钟
        redisTemplate.expire(title, 5, TimeUnit.MINUTES);


        return RestResponse.success(goodsByTitle);
    }

}
